package factories;

import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.Properties;

public class BeanFactory_CGLIBProxy {

    public static<T> T getBean(Class<T> cls) throws InstantiationException, IllegalAccessException {
        return cls.newInstance();
    }


    public static Object getBean(String id){

        try {
            Properties properties = new Properties();
            properties.load(BeanFactory_CGLIBProxy.class.getClassLoader().getResourceAsStream("bean.properties"));

            String className = properties.getProperty(id);

            //在不知道业务对象内部具体实现的情况下，要对业务对象内部某些方法【find相关的】进行功能增强【缓存处理】
            /**
             *      *** 动态代理
             *          CGLIB代理 - 不局限于接口
             *
             *          生成的类是直接继承目标类的
             */

            //目标对象 （需要增强的目标）
            Object target = Class.forName(className).newInstance();

            //① 目标类的类型
            Class cls = target.getClass();
            //② 回调对象 - 当调用代理对象的任务方法，都是这个回调对象中的intercept方法执行
            Callback invoke = new MethodInterceptor() {

                /**
                 *
                 * @param o  当前代理对象(一般不常用)
                 * @param method 代理对象调用的方法的反射对象形式
                 * @param objects 代理对象调用的方法的参数值
                 * @param methodProxy 目标类中的方法  执行super.操作的方法对象 （不常用）
                 * @return
                 * @throws Throwable
                 */
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                    String methodName = method.getName();
                    if (methodName.startsWith("find")){
                        System.out.println("缓存增强....");
                    }

                    //执行目标对象的同名方法
                    Object result = method.invoke(target, objects);

                    System.out.println("后置逻辑");
                    return result;
                }
            };

            //返回一个增强功能的代理对象
            return Enhancer.create(cls,invoke);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
